package TimeInterval

import (
	"errors"
	"sync"
	"time"
)

type TimeInterval struct {
	mutex       sync.Mutex
	lastTimeMap map[string]int64
}

func (e *TimeInterval) GetFixTime(currentTime int64, timeInterval int, timeUnit string) (int64, error) {
	tm := time.UnixMilli(currentTime)
	if timeUnit == "second" {
		value := (tm.Second() / timeInterval) * timeInterval
		return time.Date(tm.Year(), tm.Month(), tm.Day(), tm.Hour(), tm.Minute(), value, 0, time.UTC).UnixMilli(), nil
	}
	if timeUnit == "minute" {
		value := (tm.Minute() / timeInterval) * timeInterval
		return time.Date(tm.Year(), tm.Month(), tm.Day(), tm.Hour(), value, 0, 0, time.UTC).UnixMilli(), nil
	}
	if timeUnit == "hour" {
		value := (tm.Hour() / timeInterval) * timeInterval
		return time.Date(tm.Year(), tm.Month(), tm.Day(), value, 0, 0, 0, time.UTC).UnixMilli(), nil
	}
	if timeUnit == "day" {
		value := (tm.Day() / timeInterval) * timeInterval
		return time.Date(tm.Year(), tm.Month(), value, 0, 0, 0, 0, time.UTC).UnixMilli(), nil
	}

	return 0, errors.New("只支持单位：day/hour/minute/second")
}

func (e *TimeInterval) Calculate(timeInterval int, timeUnit string) (int64, error) {
	if timeUnit == "second" {
		return int64(timeInterval) * 1000, nil
	}
	if timeUnit == "minute" {
		return int64(timeInterval) * 1000 * 60, nil
	}
	if timeUnit == "hour" {
		return int64(timeInterval) * 1000 * 3600, nil
	}
	if timeUnit == "day" {
		return int64(timeInterval) * 1000 * 3600 * 24, nil
	}

	return 0, errors.New("只支持单位：day/hour/minute/second")
}

func (e *TimeInterval) TestLastTime(key string, currentTime, timeInterval int64) bool {
	return e.testLastTime(key, time.Now().UnixMilli(), timeInterval)
}

func (e *TimeInterval) testLastTime(key string, currentTime int64, timeInterval int64) bool {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	if timeInterval == -1 {
		return false
	}

	if e.lastTimeMap == nil {
		e.lastTimeMap = make(map[string]int64)
	}

	// 检查：是否到了执行周期
	lastTime := e.lastTimeMap[key]
	if time.Now().UnixMilli()-lastTime <= timeInterval {
		return false
	}

	e.lastTimeMap[key] = currentTime
	return true
}
